iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0
自我挑戰組

Go in 3o系列 第 7

[Day07] Go in 30 - 簡易自訂型別(custom types)、結構(Struct)介紹

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20230922/20162693RdGdINP4q3.png
(圖片來源:Reddit - Currently, learning golang and it feels a bit like this, can anyone relate?)

一、本篇摘要

本篇文章會介紹的是:

  • 簡易自訂型別(custom types)
  • 結構(struct)中,一般結構、匿名結構

二、簡易自訂型別(custom types)

自訂型別的行為就跟其核心型別一樣,包括有零值、能更同型別的資料比對等,但自訂型別不能直接和他根據的核心型別相互作比較,除非轉換成其型別。

type MyInt int

上面的代碼創建了一個新型別 MyInt,它是 int 的一種別名。這樣做的好處是可以為 MyInt 型別添加額外的方法(加上自訂的行為),與核心型別的差別在於此,在等下就會介紹到結構型別時就會解釋"方法"的部分。

範例說明:

package main

import "fmt"


type id string //自訂型別

func getIDs()(id, id, id){
    //用自訂型別建立變數
    var id1 id
    var id2 id = "1234-5678"
    var id3 id

    id3 ="1234-5678"
    return id1, id2, id3
}

func main() {

    id1, id2, id3 := getIDs()
    //自訂型別相互比較
    fmt.Println("id1 == id2 :", id1 == id2)
    fmt.Println("id1 == id2 :", id2 == id3)
    fmt.Println("id2 == \"1234-5678\":", string(id2) == "1234-5678")
}

輸出:
https://ithelp.ithome.com.tw/upload/images/20230922/20162693NxzA6MoLY4.png

補充 型別別名(alias)

Go 語言允許我們替型別取別名(alias), 這樣並不會創造出新型別,而是讓你能使用不同名稱來使用該型別。
例如 :

type <別名> = <型別>

假設我們定義一個 "type num = int" 則會替int型別創造一個別名num,於是你能將num當成int使用,但它仍然會被視為int型別。

三、結構(struct)的定義

定義:

 type <結構型別名稱> struct {
     <欄位1> <型別>
     <欄位2> <型別>
     ...
     <欄位N> <型別>
 }

說明:

欄位的意思就是屬於這個結構的變數。
每個欄位都必須要獨一無二,但其型別無限制。

3.1讀取、賦值

<結構變數名稱>.<欄位名稱>

3.2 重點來了 看你來像是物件導向?

Go語言不是物件導向語言,而結構就是他最近於Class的東西,Go的設計者特意簡化結構設計,關鍵的差異在於結構無
法被繼承
,因為他認為繼承在真實開發中弊多於利。

當然,還是有人(包括go文件)會出於習慣稱結構為物件,欄位稱作屬性。

範例如下 :

package main

import (
    "fmt"
)

// 定義一個結構型別叫做 "Person"
type Person struct {
    FirstName string
    LastName  string
    Age       int
}

func main() {
    // 創建一個 "Person" 結構的實例
    person1 := Person{
        FirstName: "John",
        LastName:  "Doe",
        Age:       30,
    }

    // 創建另一個 "Person" 結構的實例
    person2 := Person{
        FirstName: "Alice",
        LastName:  "Smith",
        Age:       25,
    }

    // 訪問結構的欄位
    fmt.Println("Person 1:", person1.FirstName, person1.LastName, "Age:", person1.Age)
    fmt.Println("Person 2:", person2.FirstName, person2.LastName, "Age:", person2.Age)
}

3.2 匿名結構(anonymous struct)
結構型別一般在package層級宣告,因為可能有多重函式需要用它建立變數,但我們也可以把結構型別定義在函示層級內,只是這麼一來就只能在該函示使用。

<結構變數名稱> := struct {
    <欄位 1> <型別>
    <欄位 2> <型別>
    ...
    <欄位 N> <型別>
}{
    <值 1>,
    <值 2>,
    ...
    <值 N>
}

這些結構將僅在該函數中可見。這種做法通常用於一次性的數據結構或在函數內部需要定義一個特定結構的情況。以下是一個例子:

package main

import (
    "fmt"
)

func main() {
    // 在函數內部定義匿名結構
    person := struct {
        FirstName string
        LastName  string
        Age       int
    }{
        FirstName: "John",
        LastName:  "Doe",
        Age:       30,
    }

    // 訪問匿名結構的欄位
    fmt.Println("Person:", person.FirstName, person.LastName, "Age:", person.Age)
}

匿名結構取值與賦值

package main

import "fmt"

func main() {
    // 定義一個匿名結構並初始化
    person := struct {
        FirstName string
        LastName  string
        Age       int
    }{
        FirstName: "John",
        LastName:  "Doe",
        Age:       30,
    }

    // 訪問匿名結構的欄位
    fmt.Println("First Name:", person.FirstName)
    fmt.Println("Last Name:", person.LastName)
    fmt.Println("Age:", person.Age)

    // 修改匿名結構的欄位值
    person.Age = 31
    fmt.Println("Updated Age:", person.Age)

    // 可以將匿名結構作為函數參數傳遞
    printPersonInfo(person)
}

func printPersonInfo(p struct {
    FirstName string
    LastName  string
    Age       int
}) {
    fmt.Println("Inside Function:")
    fmt.Println("First Name:", p.FirstName)
    fmt.Println("Last Name:", p.LastName)
    fmt.Println("Age:", p.Age)
}

在這個示例中,我們首先定義了一個匿名結構 person,然後初始化它並訪問它的欄位。我們還演示了如何修改結構的欄位值。最後,我們將匿名結構作為參數傳遞給 printPersonInfo 函數,以顯示如何在函數中使用匿名結構。匿名結構的欄位取值和賦值與命名結構相同,只是它們的作用域僅限於定義它們的函數。

關於結構與匿名結構初步整理到這,會再慢慢編輯更新,接下來一篇會說明如何比較結構、內嵌結構等~~寫些。


上一篇
[Day06] Go in 30 - 複合型別
下一篇
[Day08] Go in 30 - 比較結構與內嵌結構
系列文
Go in 3o30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言